#include "MQTTSub.h"
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <map>
#include "MQTTClient.h"
#include "ThreadManager.h"

#define random(x) (rand()%x)

#define ADDRESS "tcp://gosuncn.kinghowe.cn:1883"
#define TOPIC "ngrokserver/+"
#define CLIENTID "ngrokserversub"
#define QOS         1
#define TIMEOUT     10000L

using namespace std;

void CMQTTSub::delivered(void *context, MQTTClient_deliveryToken dt)
{
	printf("Message with token value %d delivery confirmed\n", dt);
}

int CMQTTSub::msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
	int i;
	char* payloadptr;

	printf("Message arrived\n");
	printf("     topic: %s\n", topicName);
	printf("   message: ");

	payloadptr = (char*)message->payload;
	for (i = 0; i < message->payloadlen; i++)
	{
		putchar(*payloadptr++);
	}
	putchar('\n');

	string data = (char*)message->payload;
	data = data.substr(0, message->payloadlen);

	printf("try to send\n");
	CMQTTSub* mqttsub = (CMQTTSub*)context;
	mqttsub->sendString2ThreadbyID(data, THREAD_PORT_MANAGER);

	MQTTClient_freeMessage(&message);
	MQTTClient_free(topicName);
	return 1;
}

void CMQTTSub::connlost(void *context, char *cause)
{
	printf("\nConnection lost\n");
	printf("     cause: %s\n", cause);
}

void CMQTTSub::test()
{	
	this;
	int num = ThreadManager::instance()->m_num++;
	printf("num:%d\n", num);
}

void CMQTTSub::initMQTT()
{	

	client.conf.address = ADDRESS;
	client.conf.clientID = CLIENTID;
	client.conf.qos = QOS;
	client.conf.topic = TOPIC;
	client.conf.timeout = TIMEOUT;
	client.conf.type = SUBSCRIBE;
	client.conf.keepAliveInterval = 20;
	client.conf.cleanSession = 1;
	client.conf.connlostCB = &connlost;
	client.conf.deliverycompleteCB = &delivered;
	client.conf.msgCB = &msgarrvd;
	client.conf.context = this;

	client.init();
}

void CMQTTSub::start()
{	
	initMQTT();

	client.startSub();
}

void CMQTTSub::handleInt(const int& item, const Theron::Address from)
{  
	if(item == 1)
		test();
	else if (item == 2)
		start();
}

int CMQTTSub::setID(int id)
{
	m_id = id;
	return 0;
}

int CMQTTSub::getID()
{
	return m_id;
}

int CMQTTSub::sendString2ThreadbyID(std::string data, int ID)
{
	map<int, Theron::Address>::iterator iter;
	iter = CDataCenter::instance()->ID_ADDRESS_MAP.find(ID);
	if (iter != CDataCenter::instance()->ID_ADDRESS_MAP.end())
	{
		printf("try to send string 2 port_manager.\n");
		Send(data, iter->second);
		return 0;
	}
	printf("send string 2 port_manager failed.\n");
	return -1;
}